<!DOCTYPE html>
<html>
<head>
<title>RTCPeerConnection.getRemoteStreams</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
// This is not an external/wpt/webrtc/ test because it tests APIs and behaviors
// that are not in the spec.

promise_test(async t => {
  const caller = new RTCPeerConnection();
  t.add_cleanup(() => caller.close());
  const callee = new RTCPeerConnection();
  t.add_cleanup(() => callee.close());
  return navigator.mediaDevices.getUserMedia({audio:true})
  .then((stream) => {
    caller.addStream(stream);
    return createAndSetOffer(caller, callee);
  }).then(() => {
    assert_stream_array_equals(caller.getLocalStreams(),
                               callee.getRemoteStreams(),
                               'Comparing local and remote streams.');
  });
}, 'callee.getRemoteStreams() should match caller.getLocalStreams() for ' +
   'one stream with one track.');

promise_test(async t => {
  const caller = new RTCPeerConnection();
  t.add_cleanup(() => caller.close());
  const callee = new RTCPeerConnection();
  t.add_cleanup(() => callee.close());
  return navigator.mediaDevices.getUserMedia({audio:true, video:true})
  .then((stream) => {
    caller.addStream(stream);
    return createAndSetOffer(caller, callee);
  }).then(() => {
    assert_stream_array_equals(caller.getLocalStreams(),
                               callee.getRemoteStreams(),
                               'Comparing local and remote streams.');
  });
}, 'callee.getRemoteStreams() should match caller.getLocalStreams() for ' +
   'one stream with two tracks.');

promise_test(async t => {
  const caller = new RTCPeerConnection({sdpSemantics:'plan-b'});
  t.add_cleanup(() => caller.close());
  const callee = new RTCPeerConnection({sdpSemantics:'plan-b'});
  t.add_cleanup(() => callee.close());
  let localStreams = null;
  return Promise.all([
      navigator.mediaDevices.getUserMedia({audio:true, video:true}),
      navigator.mediaDevices.getUserMedia({audio:true, video:true})
  ]).then((streams) => {
    localStreams = streams;
    caller.addStream(localStreams[0]);
    caller.addStream(localStreams[1]);
    return createAndSetOffer(caller, callee);
  }).then(() => {
    assert_stream_array_equals(
        caller.getLocalStreams(), callee.getRemoteStreams(),
        'Comparing local and remote streams after adding two streams.');
    // Remove the first stream.
    caller.removeStream(localStreams[0]);
    return createAndSetOffer(caller, callee);
  }).then(() => {
    assert_stream_array_equals(
        caller.getLocalStreams(), callee.getRemoteStreams(),
        'Comparing local and remote streams after removing the first stream.');
    // Re-add the first stream. This should change the stream order.
    caller.addStream(localStreams[0]);
    assert_array_equals(caller.getLocalStreams(),
                        [ localStreams[1], localStreams[0] ]);
    return createAndSetOffer(caller, callee);
  }).then(() => {
    assert_stream_array_equals(
        caller.getLocalStreams(), callee.getRemoteStreams(),
        'Comparing local and remote streams after re-adding the first stream.');
  });
}, 'callee.getRemoteStreams() should match caller.getLocalStreams() for ' +
   'a stream that is removed and re-added.');

function createAndSetOffer(caller, callee) {
  let description = null;
  return caller.createOffer()
  .then(offer => {
    description = offer;
    return caller.setLocalDescription(description);
  }).then(() => {
    return callee.setRemoteDescription(description);
  });
}

// The streams are considered equal if their IDs and track IDs match.
function assert_stream_equals(streamA, streamB, description) {
  assert_equals(streamA.id, streamB.id,
                description + ' The stream IDs don\'t match.');
  assert_equals(streamA.getTracks().length, streamB.getTracks().length,
                description + ' The number of tracks don\'t match.');
  for (let i = 0; i < streamA.getTracks().length; ++i) {
    assert_equals(streamA.getTracks()[i].id, streamB.getTracks()[i].id,
                  description + ' The ' + i + '-th track IDs don\'t match.');
  }
}

function assert_stream_array_equals(streamsA, streamsB, description) {
  assert_equals(streamsA.length, streamsB.length,
                description + ' The number of streams don\'t match.');
  for (let i = 0; i < streamsA.length; ++i) {
    assert_stream_equals(
        streamsA[i], streamsB[i],
        description + ' The ' + i + '-th streams don\'t match.');
  }
}
</script>
</body>
</html>
